import { Form, Spin, Select, Button, message, Input, Typography, Tooltip } from 'antd';
import React, { useEffect, useState } from 'react';
import request from '@/utils/request';
import { GlobalFormLayout } from '@/layouts/Form';
import styles from './index.less';
import CustomHandlerSelector from '@/components/CustomHandlerSelector';
import { hasMoreThanOne } from '@/utils/utils';
import Space from '@/components/Space';

const { Text } = Typography;

function InvocationConfig({
  invocationId,
  versionId,
  form,
  readOnly,
  onCancel,
  onSaveAndValidVersion,
}) {
  const { getFieldDecorator, getFieldValue, setFieldsValue, validateFields } = form;

  const [loading, setLoading] = useState(true);
  const [data, setData] = useState({});

  useEffect(() => {
    request
      .get('/invocation/queryVersionData', { params: { versionId } })
      .then(data => {
        if (data) {
          setFieldsValue({
            invocationType: data.invocationType,
            invocationVersionId: data.invocationVersionId,
            configId: data.configId,
          });
          setData({
            ...data,
            customInvoker:
              data.invocationType === 'SpecialInterface'
                ? [{ className: data.className, params: data.params }]
                : undefined,
          });
        }
      })
      .finally(() => setLoading(false));
  }, [setFieldsValue, versionId]);

  function getFormData(fieldValues) {
    return {
      ...fieldValues,
      className:
        fieldValues.invocationType === 'SpecialInterface'
          ? fieldValues.customInvoker.className
          : fieldValues.className,
      params:
        fieldValues.invocationType === 'SpecialInterface'
          ? fieldValues.customInvoker.params
          : undefined,
    };
  }

  const save = () => {
    validateFields((err, fieldValues) => {
      if (err) {
        return;
      }
      const data = getFormData(fieldValues);
      setLoading(true);
      request
        .post('/invocation/saveVersionData', {
          data,
        })
        .then(() => {
          message.success('保存成功');
          onCancel();
        })
        .finally(() => {
          setLoading(false);
        });
    });
  };

  const saveAndValid = () => {
    validateFields((err, fieldValues) => {
      if (err) {
        return;
      }
      let data = getFormData(fieldValues);
      data = {
        ...data,
        invocationId,
      };
      setLoading(true);
      request
        .post('/invocation/saveAndValidVersion', {
          data,
        })
        .then(() => {
          message.success('保存并生效成功');
          onCancel();
          onSaveAndValidVersion && onSaveAndValidVersion();
        })
        .finally(() => {
          setLoading(false);
        });
    });
  };

  const invocationType = getFieldValue('invocationType');

  function renderForm() {
    return (
      <Form {...GlobalFormLayout}>
        <Form.Item>{getFieldDecorator('configId')(<Input hidden />)}</Form.Item>
        <Form.Item>
          {getFieldDecorator('invocationVersionId', { initialValue: versionId })(<Input hidden />)}
        </Form.Item>
        <Form.Item label="调用类型">
          {getFieldDecorator('invocationType', {
            initialValue: 'SpecialInterface',
            rules: [
              {
                required: true,
              },
            ],
          })(
            <Select placeholder="--请选择--">
              <Select.Option key="SpecialInterface" value="SpecialInterface">
                自定义调用器
              </Select.Option>
              <Select.Option key="SpringBean" value="SpringBean">
                SpringBean
              </Select.Option>
            </Select>
          )}
        </Form.Item>

        {invocationType === 'SpringBean' && (
          <>
            <Form.Item label="BeanName">
              {getFieldDecorator('className', {
                initialValue: data.className,
                rules: [
                  {
                    required: true,
                    message: 'BeanName不能为空',
                  },
                ],
              })(<Input placeholder="请输入" />)}
            </Form.Item>
            <Form.Item label="调用方法名">
              {getFieldDecorator('methodName', {
                initialValue: data.methodName,
                rules: [
                  {
                    required: true,
                    message: '调用方法名不能为空',
                  },
                ],
              })(<Input placeholder="请输入" />)}
            </Form.Item>
            <Tooltip title={getFieldValue('argumentType')}>
              <Form.Item label="入参类型" extra="请确保方法的入参个数有且只有一个">
                {getFieldDecorator('argumentType', {
                  initialValue: data.argumentType,
                  rules: [
                    {
                      required: true,
                      message: '入参类型不能为空',
                    },
                  ],
                })(
                  <Input
                    allowClear
                    placeholder="com.iwhalecloud.tangram.standalone.example.OrderQueryDTO"
                    addonAfter={
                      <Text
                        className={styles.copyable}
                        copyable={{ text: getFieldValue('argumentType') }}
                      />
                    }
                  />
                )}
              </Form.Item>
            </Tooltip>
          </>
        )}

        {invocationType === 'SpecialInterface' && (
          <>
            <Form.Item label="自定义调用器">
              {getFieldDecorator('customInvoker', {
                initialValue: hasMoreThanOne(data.customInvoker)
                  ? data.customInvoker[0]
                  : undefined,
                rules: [
                  {
                    validator(rule, value, cb) {
                      if (value && value.className) {
                        cb();
                      } else {
                        cb('自定义调用器不能为空');
                      }
                    },
                  },
                ],
              })(<CustomHandlerSelector url="/invocation/listCustomInvokers" />)}
            </Form.Item>
          </>
        )}
      </Form>
    );
  }

  function renderFooter() {
    if (readOnly) {
      return null;
    }
    return (
      <div className="modal-footer">
        <Space className="pull-right">
          <Button style={{ marginRight: 8 }} onClick={onCancel}>
            取消
          </Button>
          <Button type="primary" onClick={save} loading={loading}>
            保存
          </Button>
          <Button type="primary" onClick={saveAndValid} loading={loading}>
            保存并生效
          </Button>
        </Space>
      </div>
    );
  }

  return (
    <>
      <Spin spinning={loading}>{renderForm()}</Spin>
      {renderFooter()}
    </>
  );
}

export default Form.create()(InvocationConfig);
